package jsonx

import (
	"strings"

	"github.com/go-kratos/kratos/v2/errors"
	"github.com/spf13/cast"
)

type StatusCode int32

const (
	StatusOK        StatusCode = 20000
	StatusDataEmpty StatusCode = 20400

	StatusBadRequest                  StatusCode = 40000
	StatusUnauthorized                StatusCode = 40100
	StatusForbidden                   StatusCode = 40300
	StatusNotFound                    StatusCode = 40400
	StatusMethodNotAllowed            StatusCode = 40500
	StatusRequestTimeout              StatusCode = 40800
	StatusGone                        StatusCode = 41000
	StatusUnsupportedMediaType        StatusCode = 41500
	StatusTooManyRequests             StatusCode = 42900
	StatusRequestHeaderFieldsTooLarge StatusCode = 43100
	StatusParamError                  StatusCode = 40001

	StatusInternalServerError StatusCode = 50000
	StatusDataHandleError     StatusCode = 50001
	StatusUnknownError        StatusCode = 50002
	StatusDataQueryError      StatusCode = 50003
	StatusFileUploadError     StatusCode = 50004
	StatusDataCreateError     StatusCode = 50005
)

var statusText = map[StatusCode]string{
	StatusOK:        "Success",
	StatusDataEmpty: "Data Empty",

	StatusBadRequest:                  "Bad Request",
	StatusUnauthorized:                "Unauthorized",
	StatusForbidden:                   "Forbidden",
	StatusNotFound:                    "Not Found",
	StatusMethodNotAllowed:            "Method Not Allowed",
	StatusRequestTimeout:              "Request Timeout",
	StatusGone:                        "Gone",
	StatusUnsupportedMediaType:        "Unsupported Media Type",
	StatusTooManyRequests:             "Too Many Requests",
	StatusRequestHeaderFieldsTooLarge: "Request Header Fields Too Large",
	StatusParamError:                  "Param Error",

	StatusInternalServerError: "Internal Server Error",
	StatusDataHandleError:     "Data Handle Error",
	StatusUnknownError:        "Unknown Error",
	StatusDataQueryError:      "Data Query Error",
	StatusFileUploadError:     "File Upload Error",
	StatusDataCreateError:     "Data Create Error",
}

// String returns the HTTP status text of the code
func (c StatusCode) String() string {
	if val, ok := statusText[c]; ok {
		return val
	}
	return statusText[StatusUnknownError]
}

// Val returns the HTTP status code
func (c StatusCode) Val() int32 {
	return int32(c)
}

// Error returns the HTTP status text that would be sent with a response
func (c StatusCode) Error(opt ...any) error {
	var msg string
	if len(opt) > 0 {
		msg = strings.Join(cast.ToStringSlice(opt), ",")
	} else {
		msg = c.String()
	}
	return errors.New(int(c), "", msg)
}

// StatusText 返回对应的状态码描述信息
// 返回空字符串表示状态码 unknown
func StatusText(code StatusCode) string {
	return statusText[code]
}
